<html>
<head>
<script src="http://code.jquery.com/jquery-1.8.2.js"></script>
<script src="http://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['controls', 'charteditor']}]}"></script>
<script src="http://jquery-csv.googlecode.com/git/src/jquery.csv.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script>
$(function() {
	google.load("visualization", "1", {packages:["corechart"]});

    var csv = $('#textInput').val();
    var data = $.csv.toArrays(csv, {
        onParseValue: $.csv.hooks.castToScalar
    });

    // Convert data for bar chart (summing all digits)
    var timeData = {};	// type -> table
    var funcRowMap;
    var maxDigit = 0;

    for (var i = 1; i < data.length; i++) {
    	var type = data[i][0];
   		var func = data[i][1];
      var digit = data[i][2];
   		var time = data[i][3];
   		if (timeData[type] == null) {
   			timeData[type] = [["Function", "Time (ns)"/*, { role: "style" }*/]];
        if (digit != 0)
   			  funcRowMap = {};
   		}

   		var table = timeData[type];
   		
      if (digit != 0) {
     		if (funcRowMap[func] == null)
     			funcRowMap[func] = table.push([func, 0]) - 1;
     		
     		table[funcRowMap[func]][1] += time;
      }
      else 
        table.push([func, time]);

      maxDigit = Math.max(maxDigit, digit);
    }

    // Compute average
    for (var type in timeData) {
      var table = timeData[type];
      for (var i = 1; i < table.length; i++)
        table[i][1] /= maxDigit;
    }

    // Convert data for drawing line chart per random digit
    var timeDigitData = {}; // type -> table
    var funcColumnMap;

    for (var i = 1; i < data.length; i++) {
    	var type = data[i][0];
   		var func = data[i][1];
		  var digit = data[i][2];
   		var time = data[i][3];

      if (digit == 0)
        continue;

   		if (timeDigitData[type] == null) {
   			timeDigitData[type] = [["Digit"]];
   			funcColumnMap = {};
   		}

   		var table = timeDigitData[type];

   		if (funcColumnMap[func] == null)
   			funcColumnMap[func] = table[0].push(func) - 1;

   		var row;
   		for (row = 1; row < table.length; row++)
   			if (table[row][0] == digit)
   				break;

    	if (row == table.length)
    		table.push([digit]);

		table[row][funcColumnMap[func]] = time;
	}

	for (var type in timeData) {
		$("#main").append(
      $("<a>", {name: type}),
      $("<h2>", {style: "padding-top: 70px; margin-top: -70px;"}).append(type)
    );

    $("#section").append($("<li>").append($("<a>", {href: "#" + type}).append(type)));

		drawTable(type, timeData[type]);
		drawBarChart(type, timeData[type]);
    if (timeDigitData[type] != null)
		  drawDigitChart(type, timeDigitData[type]);
	}

	$(".chart").each(function() {
		var chart = $(this);
		var d = $("#downloadDD").clone().css("display", "");
		$('li a', d).each(function() {
	        $(this).click(function() {
	            var svg = chart[0].getElementsByTagName('svg')[0].parentNode.innerHTML;
	            svg=sanitize(svg);
	            $('#imageFilename').val($("#title").html() + "_" + chart.data("filename"));
	            $('#imageGetFormTYPE').val($(this).attr('dltype'));
	            $('#imageGetFormSVG').val(svg);
	            $('#imageGetForm').submit();
	        });
	    });		
		$(this).after(d);
	});

  // Add configurations
  var thisConfig = "corei7920@2.67_win32_vc2013";
  var configurations = ["corei7920@2.67_cygwin32_gcc4.8","corei7920@2.67_cygwin64_gcc4.8","corei7920@2.67_win32_vc2013","corei7920@2.67_win64_vc2013"];

  for (var i in configurations) {
    var c = configurations[i];
    $("#configuration").append($("<li>", {class : (c == thisConfig ? "active" : "")}).append($("<a>", {href: c + ".html"}).append(c)));
  }
});

function drawTable(type, timeData) {
	var data = google.visualization.arrayToDataTable(timeData);
    data.addColumn('number', 'Speedup');
    data.sort([{ column: 1, desc: true }]);
    var formatter1 = new google.visualization.NumberFormat({ fractionDigits: 3 });
    formatter1.format(data, 1);

	var div = document.createElement("div");
	div.className = "tablechart";
	$("#main").append(div);
    var table = new google.visualization.Table(div);
    redrawTable(0);
    table.setSelection([{ row: 0, column: null}]);

    function redrawTable(selectedRow) {
        // Compute relative time using the first row as basis
        var basis = data.getValue(selectedRow, 1);
        for (var rowIndex = 0; rowIndex < data.getNumberOfRows(); rowIndex++)
            data.setValue(rowIndex, 2, basis / data.getValue(rowIndex, 1));

        var formatter = new google.visualization.NumberFormat({suffix: 'x'});
        formatter.format(data, 2); // Apply formatter to second column

        table.draw(data);
    }

    google.visualization.events.addListener(table, 'select',
    function() {
        var selection = table.getSelection();
        if (selection.length > 0) {
            var item = selection[0];
            if (item.row != null)
                redrawTable(item.row);
        }
    });

}

function drawBarChart(type, timeData) {
    var defaultColors = ["#3366cc","#dc3912","#ff9900","#109618","#990099","#0099c6","#dd4477","#66aa00","#b82e2e","#316395","#994499","#22aa99","#aaaa11","#6633cc","#e67300","#8b0707","#651067","#329262","#5574a6","#3b3eac","#b77322","#16d620","#b91383","#f4359e","#9c5935","#a9c413","#2a778d","#668d1c","#bea413","#0c5922","#743411"];

	var data = google.visualization.arrayToDataTable(timeData);
	data.addColumn({ type: "string", role: "style" })
	for (var rowIndex = 0; rowIndex < data.getNumberOfRows(); rowIndex++)
		data.setValue(rowIndex, 2, defaultColors[rowIndex]);

    data.sort([{ column: 1, desc: true }]);
	var options = { 
		title: type,
		chartArea: {'width': '70%', 'height': '70%'},
		width: 800,
		height: 300,
		legend: { position: "none" },
		hAxis: { title: "Time (ns)" }
	};
	var div = document.createElement("div");
	div.className = "chart";
	$(div).data("filename", type + "_time");
	$("#main").append(div);
	var chart = new google.visualization.BarChart(div);

	chart.draw(data, options);
}

function drawDigitChart(type, timeDigitData) {
	var data = google.visualization.arrayToDataTable(timeDigitData);

	var options = { 
		title: type,
		chartArea: {'width': '70%', 'height': '80%'},
		hAxis: {
			title: "Digit",
			gridlines: { count: timeDigitData.length - 1 },
			maxAlternation: 1,
			minTextSpacing: 0
		},
		vAxis: {
			title: "Time (ns) in log scale",
			logScale: true,
			minorGridlines: { count: 10 },
      baseline: 0
		},
		width: 800,
		height: 600
	};
	var div = document.createElement("div");
	div.className = "chart";
	$(div).data("filename", type + "_timedigit");
	$("#main").append(div);
	var chart = new google.visualization.LineChart(div);

	chart.draw(data, options);
}

// http://jsfiddle.net/P6XXM/
function sanitize(svg) {
    svg = svg
        .replace(/\<svg/,'<svg xmlns="http://www.w3.org/2000/svg" version="1.1"')
        .replace(/zIndex="[^"]+"/g, '')
        .replace(/isShadow="[^"]+"/g, '')
        .replace(/symbolName="[^"]+"/g, '')
        .replace(/jQuery[0-9]+="[^"]+"/g, '')
        .replace(/isTracker="[^"]+"/g, '')
        .replace(/url\([^#]+#/g, 'url(#')
        .replace('<svg xmlns:xlink="http://www.w3.org/1999/xlink" ', '<svg ')
        .replace(/ href=/g, ' xlink:href=')
    /*.replace(/preserveAspectRatio="none">/g, 'preserveAspectRatio="none"/>')*/
    /* This fails in IE < 8
    .replace(/([0-9]+)\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
    return s2 +'.'+ s3[0];
    })*/

    // IE specific
        .replace(/id=([^" >]+)/g, 'id="$1"')
        .replace(/class=([^" ]+)/g, 'class="$1"')
        .replace(/ transform /g, ' ')
        .replace(/:(path|rect)/g, '$1')
        .replace(/<img ([^>]*)>/gi, '<image $1 />')
        .replace(/<\/image>/g, '') // remove closing tags for images as they'll never have any content
        .replace(/<image ([^>]*)([^\/])>/gi, '<image $1$2 />') // closes image tags for firefox
        .replace(/width=(\d+)/g, 'width="$1"')
        .replace(/height=(\d+)/g, 'height="$1"')
        .replace(/hc-svg-href="/g, 'xlink:href="')
        .replace(/style="([^"]+)"/g, function (s) {
            return s.toLowerCase();
        });

    // IE9 beta bugs with innerHTML. Test again with final IE9.
    svg = svg.replace(/(url\(#highcharts-[0-9]+)&quot;/g, '$1')
        .replace(/&quot;/g, "'");
    if (svg.match(/ xmlns="/g).length == 2) {
        svg = svg.replace(/xmlns="[^"]+"/, '');
    }

    return svg;
}
</script>
<style type="text/css">
@media (min-width: 800px) {
  .container {
    max-width: 800px;
  }
}
textarea {
	font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
}
.tablechart {
	width: 700px;
	margin: auto;
	padding-top: 20px;
	padding-bottom: 20px;
}
.chart {
	padding-top: 20px;
	padding-bottom: 20px;
}
body { padding-top: 70px; }
</style>
</head>
<body>
<div class="container">
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
  <div class="container">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="https://github.com/miloyip/dtoa-benchmark"><span class="glyphicon glyphicon-home"></span> dtoa-benchmark</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Configuration <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu" id="configuration">
          </ul>
        </li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Section <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu" id="section">
          </ul>
        </li>
      </ul>
      <p class="navbar-text navbar-right">Developed by <a href="https://github.com/miloyip" class="navbar-link">Milo Yip</a></p>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>
<div class="page-header">
<h1 id="title">corei7920@2.67_win32_vc2013</h1>
</div>
<div id="main"></div>
<h2>Source CSV</h2>
<textarea id="textInput" class="form-control" rows="5" readonly>
doubleype,Function,Digit,doubleime(ms)
randomdigit,doubleconv,1,296.024842
randomdigit,doubleconv,2,320.759669
randomdigit,doubleconv,3,326.475958
randomdigit,doubleconv,4,345.670735
randomdigit,doubleconv,5,359.053441
randomdigit,doubleconv,6,386.064055
randomdigit,doubleconv,7,389.221041
randomdigit,doubleconv,8,409.749108
randomdigit,doubleconv,9,415.794888
randomdigit,doubleconv,10,435.614166
randomdigit,doubleconv,11,427.281104
randomdigit,doubleconv,12,458.111517
randomdigit,doubleconv,13,453.544616
randomdigit,doubleconv,14,486.930502
randomdigit,doubleconv,15,481.999628
randomdigit,doubleconv,16,499.520131
randomdigit,doubleconv,17,518.753221
randomdigit,fpconv,1,321.077666
randomdigit,fpconv,2,340.850968
randomdigit,fpconv,3,380.351598
randomdigit,fpconv,4,405.488710
randomdigit,fpconv,5,427.679558
randomdigit,fpconv,6,445.131097
randomdigit,fpconv,7,459.716829
randomdigit,fpconv,8,474.930893
randomdigit,fpconv,9,485.329022
randomdigit,fpconv,10,495.497273
randomdigit,fpconv,11,505.899233
randomdigit,fpconv,12,516.408469
randomdigit,fpconv,13,527.358304
randomdigit,fpconv,14,537.411617
randomdigit,fpconv,15,546.009038
randomdigit,fpconv,16,554.583471
randomdigit,fpconv,17,570.038907
randomdigit,gay,1,866.239988
randomdigit,gay,2,1109.205256
randomdigit,gay,3,1401.670827
randomdigit,gay,4,1671.842105
randomdigit,gay,5,1949.369465
randomdigit,gay,6,2216.502528
randomdigit,gay,7,2483.762023
randomdigit,gay,8,2753.373932
randomdigit,gay,9,3015.323256
randomdigit,gay,10,3263.250047
randomdigit,gay,11,3635.092344
randomdigit,gay,12,3997.210819
randomdigit,gay,13,4271.393460
randomdigit,gay,14,4498.964593
randomdigit,gay,15,4761.189770
randomdigit,gay,16,5046.563618
randomdigit,gay,17,5162.674779
randomdigit,grisu2,1,270.891561
randomdigit,grisu2,2,296.672331
randomdigit,grisu2,3,317.024158
randomdigit,grisu2,4,324.288289
randomdigit,grisu2,5,340.264781
randomdigit,grisu2,6,354.490371
randomdigit,grisu2,7,367.670018
randomdigit,grisu2,8,377.796125
randomdigit,grisu2,9,392.240099
randomdigit,grisu2,10,401.324095
randomdigit,grisu2,11,408.457962
randomdigit,grisu2,12,424.120287
randomdigit,grisu2,13,431.208179
randomdigit,grisu2,14,442.096713
randomdigit,grisu2,15,452.410554
randomdigit,grisu2,16,465.502081
randomdigit,grisu2,17,485.106807
randomdigit,milo,1,181.982579
randomdigit,milo,2,200.142907
randomdigit,milo,3,219.487105
randomdigit,milo,4,232.069071
randomdigit,milo,5,251.026308
randomdigit,milo,6,263.278782
randomdigit,milo,7,276.328166
randomdigit,milo,8,287.580673
randomdigit,milo,9,297.932826
randomdigit,milo,10,306.422971
randomdigit,milo,11,314.652588
randomdigit,milo,12,324.525830
randomdigit,milo,13,332.947011
randomdigit,milo,14,339.931458
randomdigit,milo,15,348.482904
randomdigit,milo,16,356.731677
randomdigit,milo,17,364.141398
randomdigit,null,1,2.498003
randomdigit,null,2,2.498003
randomdigit,null,3,2.498003
randomdigit,null,4,2.498003
randomdigit,null,5,2.498003
randomdigit,null,6,2.498003
randomdigit,null,7,2.498003
randomdigit,null,8,2.498003
randomdigit,null,9,2.498003
randomdigit,null,10,2.498003
randomdigit,null,11,2.498003
randomdigit,null,12,2.498003
randomdigit,null,13,2.498003
randomdigit,null,14,2.498003
randomdigit,null,15,2.498003
randomdigit,null,16,2.498003
randomdigit,null,17,2.498003
randomdigit,ostringstream,1,2874.415967
randomdigit,ostringstream,2,2877.975238
randomdigit,ostringstream,3,2895.043648
randomdigit,ostringstream,4,2899.832764
randomdigit,ostringstream,5,2917.046763
randomdigit,ostringstream,6,2930.402650
randomdigit,ostringstream,7,2937.570999
randomdigit,ostringstream,8,2932.444729
randomdigit,ostringstream,9,2948.459533
randomdigit,ostringstream,10,2980.408684
randomdigit,ostringstream,11,2984.956429
randomdigit,ostringstream,12,2994.316277
randomdigit,ostringstream,13,2995.695542
randomdigit,ostringstream,14,3006.335043
randomdigit,ostringstream,15,3022.234908
randomdigit,ostringstream,16,3010.085878
randomdigit,ostringstream,17,3004.423228
randomdigit,ostrstream,1,2703.996230
randomdigit,ostrstream,2,2703.314260
randomdigit,ostrstream,3,2715.160617
randomdigit,ostrstream,4,2722.424749
randomdigit,ostrstream,5,2732.987623
randomdigit,ostrstream,6,2736.516244
randomdigit,ostrstream,7,2747.826220
randomdigit,ostrstream,8,2753.228343
randomdigit,ostrstream,9,2764.385068
randomdigit,ostrstream,10,2787.012683
randomdigit,ostrstream,11,2792.916706
randomdigit,ostrstream,12,2789.123726
randomdigit,ostrstream,13,2797.606208
randomdigit,ostrstream,14,2813.061644
randomdigit,ostrstream,15,2817.007875
randomdigit,ostrstream,16,2819.620817
randomdigit,ostrstream,17,2803.606013
randomdigit,sprintf,1,1293.486611
randomdigit,sprintf,2,1284.831720
randomdigit,sprintf,3,1301.248810
randomdigit,sprintf,4,1307.076206
randomdigit,sprintf,5,1313.462972
randomdigit,sprintf,6,1319.688822
randomdigit,sprintf,7,1342.557809
randomdigit,sprintf,8,1357.254649
randomdigit,sprintf,9,1361.825381
randomdigit,sprintf,10,1352.170523
randomdigit,sprintf,11,1358.978731
randomdigit,sprintf,12,1354.496118
randomdigit,sprintf,13,1364.361697
randomdigit,sprintf,14,1369.714013
randomdigit,sprintf,15,1362.342606
randomdigit,sprintf,16,1373.514656
randomdigit,sprintf,17,1337.446865
</textarea>
</div>
<div class="row" id="downloadDD" style="display: none">
<div class="btn-group pull-right" >
    <button class="btn dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-picture"></span></button>
    <ul class="dropdown-menu">
        <li><a tabindex="-1" href="#" dltype="image/jpeg">JPEG</a></li>
        <li><a tabindex="-1" href="#" dltype="image/png">PNG</a></li>
        <li><a tabindex="-1" href="#" dltype="application/pdf">PDF</a></li>
        <li><a tabindex="-1" href="#" dltype="image/svg+xml">SVG</a></li>
    </ul>
</div>
</div>
<form method="post" action="http://export.highcharts.com/" id="imageGetForm">
    <input type="hidden" name="filename" id="imageFilename" value="" />
    <input type="hidden" name="type" id="imageGetFormTYPE" value="" />
    <input type="hidden" name="width" value="900" />
    <input type="hidden" name="svg" value="" id="imageGetFormSVG" />
</form>
</div>
</body>
</html>